package com.swak.wechat;

import java.util.concurrent.CompletableFuture;

import com.swak.http.HttpService;
import com.swak.utils.StringUtils;
import com.swak.wechat.token.AccessToken;
import com.swak.wechat.user.SessionToken;

/**
 * Wechat 服务
 *
 * @author: lifeng
 * @date: 2020/4/1 11:38
 */
public abstract class AbstractMpService {

	/**
	 * Http 服务
	 *
	 * @return http 服务
	 */
	public abstract HttpService getHttpService();

	// ==========================================================
	// 小程序登陆
	// ==========================================================

	/**
	 * 小程序登录： 主要是换取： session_key
	 *
	 * @param app  app
	 * @param code code
	 * @return 异步结果
	 */
	public CompletableFuture<SessionToken> oauth2Session(WechatConfig app, String code) {
		if (!(StringUtils.isNotBlank(code))) {
			return CompletableFuture.completedFuture(null);
		}
		CompletableFuture<SessionToken> future = this.getHttpService().get()
				.setUrl("https://api.weixin.qq.com/sns/jscode2session").addQueryParam("appid", app.getAppId())
				.addQueryParam("secret", app.getSecret()).addQueryParam("js_code", code)
				.addQueryParam("grant_type", "authorization_code").jsonResult(SessionToken.class).future();
		return future.thenApply(res -> {
			if (res != null) {
				res.setCode(code);
				res.setAppId(app.getAppId());
			}
			return res;
		});
	}
	
	// ==========================================================
	// 调用 API 的token
	// ==========================================================

	/**
	 * 获取接入系统的 accessToken
	 *
	 * @param app app
	 * @return 异步结果
	 */
	public CompletableFuture<AccessToken> accessToken(WechatConfig app) {
		CompletableFuture<AccessToken> future = this.getHttpService().get()
				.setUrl("https://api.weixin.qq.com/cgi-bin/token").addQueryParam("grant_type", "client_credential")
				.addQueryParam("appid", app.getAppId()).addQueryParam("secret", app.getSecret())
				.jsonResult(AccessToken.class).future();
		return future.thenApply(token -> {
			if (token != null) {
				token.setAddTime(System.currentTimeMillis());
			}
			return token;
		});
	}
}
